package com.ruoyi.service.impl;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.domain.SpaceCollection;
import com.ruoyi.domain.SpaceDirectory;
import com.ruoyi.domain.SpaceDocument;
import com.ruoyi.dto.SpaceDirectoryTree;
import com.ruoyi.mapper.SpaceCollectionMapper;
import com.ruoyi.mapper.SpaceDirectoryMapper;
import com.ruoyi.mapper.SpaceDocumentMapper;
import com.ruoyi.mapper.SpaceRecordMapper;
import com.ruoyi.platform.constant.UserConstants;
import com.ruoyi.platform.service.impl.BaseServiceImpl;
import com.ruoyi.platform.utils.BeanUtils;
import com.ruoyi.platform.utils.StringUtils;
import com.ruoyi.service.IMFileService;
import com.ruoyi.service.ISpaceDirectoryService;
import com.ruoyi.service.ISpaceDocumentService;
import com.ruoyi.utils.BaseFileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 智联空间文件夹Service业务层处理
 *
 * @author ruoyi
 * @date 2022-12-19
 */
@Service
public class SpaceDirectoryServiceImpl extends BaseServiceImpl<SpaceDirectoryMapper, SpaceDirectory> implements ISpaceDirectoryService {

    @Autowired
    private SpaceDirectoryMapper spaceDirectoryMapper;

    @Autowired
    private ISpaceDocumentService spaceDocumentService;

    @Autowired
    private BaseFileUtils baseFileUtils;

    @Autowired
    private IMFileService fileService;

    @Autowired
    private SpaceCollectionMapper collectionMapper;

    @Autowired
    private SpaceRecordMapper recordMapper;

    /**
     * 查询智联空间文件夹
     *
     * @param id 智联空间文件夹主键
     * @return 智联空间文件夹
     */
    @Override
    public SpaceDirectory selectSpaceDirectoryById(Long id) {
        return spaceDirectoryMapper.selectSpaceDirectoryById(id);
    }

    /**
     * 查询智联空间文件夹列表
     *
     * @param spaceDirectory 智联空间文件夹
     * @return 智联空间文件夹
     */
    @Override
    public List<SpaceDirectory> selectSpaceDirectoryList(SpaceDirectory spaceDirectory) {
        return spaceDirectoryMapper.selectSpaceDirectoryList(spaceDirectory);
    }

    /**
     * 新增智联空间文件夹
     *
     * @param spaceDirectory 智联空间文件夹
     * @return 结果
     */
    @Transactional
    @Override
    public int insertSpaceDirectory(SpaceDirectory spaceDirectory) {
        if(StringUtils.isNull(spaceDirectory.getParentId())||spaceDirectory.getParentId()==0L){
            spaceDirectory.setAncestors("0");
            spaceDirectory.setParentId(0L);
            spaceDirectory.setLevel(1);
        }else {
            SpaceDirectory info = getById(spaceDirectory.getParentId());
            spaceDirectory.setAncestors(info.getAncestors() + "," + spaceDirectory.getParentId());
            spaceDirectory.setLevel(spaceDirectory.getAncestors().split(",").length);
        }

        return baseMapper.insert(spaceDirectory);
    }

    /**
     * 修改智联空间文件夹
     *
     * @param spaceDirectory 智联空间文件夹
     * @return 结果
     */
    @Transactional
    @Override
    public int updateSpaceDirectory(SpaceDirectory spaceDirectory) {
        SpaceDirectory newParent = getById(spaceDirectory.getParentId());
        SpaceDirectory old = getById(spaceDirectory.getId());
        Assert.isTrue(!UserConstants.NOT_UNIQUE.equals(checkDirectoryNameUnique(spaceDirectory)), "失败，文件夹已存在");
        Assert.isTrue(!UserConstants.NOT_UNIQUE.equals(checkDirectoryNameUnique(spaceDirectory)), "修改文件夹'" + spaceDirectory.getName() + "'失败，上级不能是自己");
        if (StringUtils.isNotNull(newParent) && StringUtils.isNotNull(old)) {
            String newAncestors = newParent.getAncestors() + "," + newParent.getId();
            String oldAncestors = old.getAncestors();
            spaceDirectory.setAncestors(newAncestors);
            updateChildren(spaceDirectory.getId(), newAncestors, oldAncestors);
        }
        return baseMapper.updateById(spaceDirectory);
    }

    /**
     * 修改子元素关系
     *
     * @param id           被修改的目录ID
     * @param newAncestors 新的父ID集合
     * @param oldAncestors 旧的父ID集合
     */
    @Transactional
    public void updateChildren(Long id, String newAncestors, String oldAncestors) {
        List<SpaceDirectory> children = baseMapper.selectChildrenById(id);
        for (SpaceDirectory child : children) {
            child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors));
        }
        if (CollectionUtils.isNotEmpty(children)) {
            updateBatchById(children);
        }
    }

    /**
     * 批量删除智联空间文件夹
     *
     * @param ids 需要删除的智联空间文件夹主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteSpaceDirectoryByIds(Long[] ids) {
        return spaceDirectoryMapper.deleteSpaceDirectoryByIds(ids);
    }

    /**
     * 删除智联空间文件夹信息
     *
     * @param id 智联空间文件夹主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteSpaceDirectoryById(Long id) {
        Assert.isFalse(hasChildById(id), "存在下级文件夹,不允许删除");
//        Assert.isFalse(checkExistDocument(id), "文件夹拥有文档,不允许删除");
        SpaceDirectory spaceDirectory = spaceDirectoryMapper.selectSpaceDirectoryById(id);
        if(StringUtils.isNotNull(spaceDirectory.getDocumentId())){
            //删除文档
            SpaceDocument spaceDocument = spaceDocumentService.selectSpaceDocumentById(spaceDirectory.getDocumentId());
            spaceDocumentService.deleteSpaceDocumentById(spaceDocument.getId());
            //删除收藏记录
            collectionMapper.deleteByDocumentIdAndCreateBy(spaceDocument.getId(),null);
            //删除阅读，下载，上传记录
            recordMapper.deleteSpaceRecordByDocumentId(spaceDocument.getId());
            if(StringUtils.isNotNull(spaceDocument.getFileId())){
                //删除minio服务器文件
                fileService.removeFileById(spaceDocument.getFileId());
            }
        }
        return spaceDirectoryMapper.deleteSpaceDirectoryById(id);
    }

    /**
     * 删除智联空间文件夹
     *
     * @param id
     * @return
     */
    @Override
    @Transactional
    public int deleteById(Long id) {
        Assert.isFalse(hasChildById(id), "存在下级文件夹,不允许删除");
        Assert.isFalse(checkExistDocument(id), "文件夹拥有文档,不允许删除");
        return spaceDirectoryMapper.deleteSpaceDirectoryById(id);
    }

    @Override
    public List<SpaceDirectory> getDirectorySelectTree(SpaceDirectory spaceDirectory) {
        List<SpaceDirectory> list = lambdaQuery().isNull(SpaceDirectory::getDocumentId).list();
        List<SpaceDirectory> treeList = buildIndexSpaceDirectoryTreeList(list);
        return treeList;
    }

    @Override
    public List<SpaceDirectory> selectFirstIndexTree(Long type) {
        return spaceDirectoryMapper.selectFirstIndexTree(type);
    }

    @Override
    public List<SpaceDirectory> selectSpaceDirectoryByParentId(Long id) {
        return spaceDirectoryMapper.selectChildrenByParentId(id);
    }


    private boolean checkExistDocument(Long id) {
        LambdaQueryWrapper<SpaceDocument> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(SpaceDocument::getId, id).eq(SpaceDocument::getDelFlag, 0).last("limit 1");
        int count = spaceDocumentService.count(queryWrapper);
        return count > 0;
    }

    private boolean hasChildById(Long id) {
        LambdaQueryWrapper<SpaceDirectory> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(SpaceDirectory::getParentId, id).eq(SpaceDirectory::getDelFlag, 0).last("limit 1");
        int count = count(queryWrapper);
        return count > 0;
    }

    /**
     * 智联空间目录树
     *
     * @param spaceDirectory
     * @return
     */
    @Override
    public List<SpaceDirectoryTree> getTreeList(SpaceDirectory spaceDirectory) {
        List<SpaceDirectory> list = baseMapper.selectSpaceDirectoryList(spaceDirectory);
        List<SpaceDirectoryTree> treeList = buildSpaceDirectoryTreeList(list);
        return treeList;
    }

    @Override
    public List<SpaceDirectory> getIndexTreeList(SpaceDirectory spaceDirectory,Long userId) {
        List<SpaceDirectory> list = baseMapper.selectSpaceDirectoryList(spaceDirectory);
        SpaceCollection spaceCollection = new SpaceCollection();
        spaceCollection.setCreateBy(String.valueOf(userId));
        for (SpaceDirectory directory : list) {
            if(StringUtils.isNotNull(directory.getDocumentId())){
                spaceCollection.setDocumentId(directory.getDocumentId());
                List<SpaceCollection> spaceCollections = collectionMapper.selectSpaceCollectionList(spaceCollection);
                if(spaceCollections.size() > 0){
                    directory.setIsCollection(1);
                }else {
                    directory.setIsCollection(0);
                }
            }
        }

        List<SpaceDirectory> treeList = buildIndexSpaceDirectoryTreeList(list);
        return treeList;
    }

    /**
     * 校验文件夹名称是否唯一
     *
     * @param spaceDirectory 目录信息
     * @return
     */
    @Override
    public String checkDirectoryNameUnique(SpaceDirectory spaceDirectory) {
        Long id = StringUtils.isNull(spaceDirectory.getId()) ? -1L : spaceDirectory.getId();
        if(spaceDirectory.getParentId()==null){
            spaceDirectory.setParentId(0L);
        }
        LambdaQueryWrapper<SpaceDirectory> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(SpaceDirectory::getName, spaceDirectory.getName())
                .eq(SpaceDirectory::getParentId, spaceDirectory.getParentId()).eq(SpaceDirectory::getDelFlag, "0");
        SpaceDirectory info = getOne(queryWrapper);
        if (StringUtils.isNotNull(info)) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }


    /**
     * 构建前端所需要下拉树结构
     *
     * @param list
     * @return 下拉树结构列表
     */
    private List<SpaceDirectoryTree> buildSpaceDirectoryTreeList(List<SpaceDirectory> list) {
        List<SpaceDirectory> trees = buildSpaceDirectoryTree(list);
        return trees.stream().map(SpaceDirectoryTree::new).collect(Collectors.toList());
    }

    private List<SpaceDirectory> buildIndexSpaceDirectoryTreeList(List<SpaceDirectory> list) {
        List<SpaceDirectory> trees = buildSpaceDirectoryTree(list);
        return trees;
    }

    private List<SpaceDirectory> buildSpaceDirectoryTree(List<SpaceDirectory> list) {
        List<SpaceDirectory> returnList = new ArrayList<>();
        List<Long> tempList = list.stream().map(x -> x.getId()).collect(Collectors.toList());
        for (SpaceDirectory d : list) {
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(d.getParentId())) {
                recursionFn(list, d);
                returnList.add(d);
            }
        }
        if (returnList.isEmpty()) {
            returnList = list;
        }
        return returnList;
    }

    /**
     * 递归列表
     *
     * @param list
     * @param d
     */
    private void recursionFn(List<SpaceDirectory> list, SpaceDirectory d) {
        // 得到子节点列表
        List<SpaceDirectory> childList = getChildList(list, d);
        d.setChildren(childList);
        for (SpaceDirectory tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<SpaceDirectory> getChildList(List<SpaceDirectory> list, SpaceDirectory t) {
        List<SpaceDirectory> tList = new ArrayList<>();
        Iterator<SpaceDirectory> it = list.iterator();
        while (it.hasNext()) {
            SpaceDirectory n = it.next();
            if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getId().longValue()) {
                if (BeanUtils.isNotEmpty(n.getDocumentId()) && n.getDocumentId() > 0L) {
                    SpaceDocument document = spaceDocumentService.get(n.getDocumentId());
                    if (BeanUtils.isNotEmpty(document)) {
                        String fileUrl = "";
                        if(BeanUtils.isNotEmpty(document.getFileId())){
                             fileUrl = baseFileUtils.getFileUrlById(document.getFileId().toString());
                             if (StringUtils.isNotNull(fileUrl)){
                                 if (fileUrl.lastIndexOf(".") != -1) {
                                     n.setCType(fileUrl.substring(fileUrl.lastIndexOf(".") + 1));
                                 }
                             }
                        }

                    }
                }
                tList.add(n);
            }
        }
        return tList;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<SpaceDirectory> list, SpaceDirectory t) {
        return getChildList(list, t).size() > 0;
    }


}
